﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RaytracerLib.MathLib.Polynomials;

namespace RaytracerLib.MathLib.RootFinders
{
    public abstract class RootFinder
    {
        public int MaxIterations;
        public double AbsoluteError;

        public RootFinder()
        {
            MaxIterations = Constants.ROOT_FINDER_MAXIMUM_ITERATIONS;
            AbsoluteError = Constants.ROOT_FINDER_ABSOLUTE_ERROR;
        }

        public static RootFinder Create(RootFindingMethod a_method)
        {
            switch (a_method)
            {
                case RootFindingMethod.Bisection: 
                    return new BisectionRootFinder();
                case RootFindingMethod.ModifedRegulaFalsi: 
                    return new ModifiedRegulaFalsiRootFinder();
                case RootFindingMethod.RegulaFalsi: 
                    return new RegulaFalsiRootFinder();
                case RootFindingMethod.Secant: 
                    return new SecantRootFinder();
                case RootFindingMethod.Newton: 
                    return new NewtonRootFinder();
                case RootFindingMethod.Halley: 
                    return new HalleyRootFinder();
                default: throw new NotImplementedException();
            }
        }

        public abstract double FindRoot(double a_a, double a_b, 
            Polynomial a_poly);
        public abstract double FindRoot(double a_a, double a_b, 
            Func<double, double> a_func);
        public abstract double FindRoot(double a_a, double a_b, 
            Func<double, double> a_func, Func<double, double> a_d1);
        public abstract double FindRoot(double a_a, double a_b, 
            Func<double, double> a_func, Func<double, double> a_d1, 
            Func<double, double> a_d2);
    }
}
